/*
 * colas.c
 *
 *  Created on: 27/09/2011
 *      Author: Power Rangers Turbo C
 */

#include <stdlib.h>
#include <stddef.h>
#include <sys/types.h>
#include "cola.h"

void cola_inicializacionCola(cola *unaCola) {
	//unaCola= (cola*) malloc(sizeof(cola));
	unaCola->tamano = 0;
	unaCola->primero = NULL;
	unaCola->ultimo = NULL;
}

void cola_meterEnCola(cola *unaCola, void *dato) {
	if (!unaCola->primero) {
		unaCola->primero = (cola_NODO*) malloc(sizeof(cola_NODO));
		unaCola->primero->dato = dato;
		unaCola->ultimo = unaCola->primero;
	} else {
		unaCola->ultimo->siguiente = (cola_NODO*) malloc(sizeof(cola_NODO));
		unaCola->ultimo = unaCola->ultimo->siguiente;
		unaCola->ultimo->dato = dato;
	}

	unaCola->ultimo->siguiente = NULL;
	unaCola->tamano++;
}

void cola_sacarDeCola(cola * unaCola) {
	cola_NODO *nodoTrabajo;

	if (unaCola->tamano) {
		nodoTrabajo = unaCola->primero;
		(unaCola->tamano)--;
		if (unaCola->tamano) {
			unaCola->primero = nodoTrabajo->siguiente;
		} else {
			unaCola->primero = NULL;
			unaCola->ultimo = NULL;
		}
		free(nodoTrabajo->dato);
		free(nodoTrabajo);
	}
}

void *cola_primero(cola *unaCola) {
	if (unaCola->tamano > 0) {
		return unaCola->primero->dato;
	} else {
		return NULL;
	}
}

void buscarMenor(cola_NODO *lista, int(*comparar)(const void*, const void*)) {
	if (lista && lista->siguiente) {
		buscarMenor(lista->siguiente, comparar); //cuando llego al final no entro a este if =>quedo en el anteultimo

		void *dato = lista->siguiente->dato;

		if (comparar(lista->dato, dato) == 1) {
			lista->siguiente->dato = lista->dato;
			lista->dato = dato;
		}

	}
}

void lista_ordenar(cola_NODO *lista, int(*comparar)(const void*, const void*)) {
	buscarMenor(lista, comparar);
	if (lista)
		lista_ordenar(lista->siguiente, comparar);
}

void cola_ordenar(cola * unaCola, int(*comparar)(const void*, const void*)) {
	cola_NODO *puntero;
	lista_ordenar(unaCola->primero, comparar);

	puntero = unaCola->primero;

	while (puntero->siguiente) {

		puntero = puntero->siguiente;

	}
	unaCola->ultimo = puntero;
}

int compararAscendenteInt(int *nro1, int *nro2) {
	if (nro1 > nro2) {
		return 1;
	}
	return 0;
}
int compararDescendenteInt(int *nro1, int *nro2) {
	if (nro1 < nro2) {
		return 1;
	}
	return 0;
}

void insertaDelante(cola_NODO *unaLista,void* dato){
	cola_NODO *ptr = (cola_NODO*) malloc(sizeof(cola_NODO));
	ptr->dato=dato;
	ptr->siguiente=unaLista;
	unaLista=ptr;
}
void insertaEnMedio(cola_NODO *unaLista, void *dato,
		int(*comparar)(const void*, const void*)){
	cola_NODO *ptr;
	cola_NODO *ptrNuevo= (cola_NODO*) malloc(sizeof(cola_NODO));
	ptrNuevo->dato=dato;
	ptrNuevo->siguiente=NULL;
	ptr=unaLista;
	while((ptr->siguiente==NULL)&&(comparar(dato,ptr->siguiente->dato)==1)){
		ptr=ptr->siguiente;
	}
	ptrNuevo->siguiente=ptr->siguiente;
	ptr->siguiente=ptrNuevo;
}
void cola_listaInsertaNodo(cola_NODO *unaLista, void *dato,
		int(*comparar)(const void*, const void*)) {
	if ((unaLista == NULL) || (comparar(dato, unaLista->dato))) {
		insertaDelante(unaLista,dato);
	}
	else{
		insertaEnMedio(unaLista,dato,comparar);
	}
}
void cola_listaSuprimeNodo(cola_NODO * unaLista, void *dato,
		int(*comparar)(const void*, const void*)) {
	cola_NODO *ptrAct = unaLista;
	cola_NODO *ptrAnt = NULL;
	while ((ptrAct != NULL) && (comparar(dato, ptrAct->dato) == 1)) { //1 es verdadero
		ptrAnt = ptrAct;
		ptrAct = ptrAct->siguiente;
	}
	if ((ptrAct != NULL) && (dato = ptrAct->dato)) {
		if (ptrAnt != NULL) {
			ptrAnt->siguiente = ptrAct->siguiente;
		} else {
			unaLista = ptrAct->siguiente;
		}
		dato = ptrAct->dato;
		free(ptrAct);
	}
}

cola_NODO *cola_listaBuscaNodo(cola_NODO *unaLista, void *dato) {
	cola_NODO *ptr = unaLista;
	cola_NODO *qtr = NULL;
	while ((ptr != NULL) && (qtr == NULL)) {
		if (dato == ptr->dato) {
			qtr = ptr;
		} else {
			ptr = ptr->siguiente;
		}
	}
	return qtr;
}
int compararAscendentePedido(PEDIDO *ped1, PEDIDO *ped2){
	if (ped1->sector > ped2->sector) {
		return 1;
	}
	return 0;
}
int compararDescendentePedido(PEDIDO *ped1, PEDIDO *ped2){
	if (ped1->sector < ped2->sector) {
		return 1;
	}
	return 0;
}
